﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.Windows.Navigation;
using System.IO;
using Sanctuary.Core;
using Sanctuary.Core.Animation;
using Sanctuary.Core.Images;
using Sanctuary.Core.Dialog;

namespace Sanctuary
{
    public partial class GameDialog: ITextControl, IImageControl
    {
        private class ImageAndImageTransform
        {
            public Image ImageUsed { get; set; }
            public ScaleTransform ImageTransform { get; set; }
        }

        private Dictionary<ImageLocation, ImageAndImageTransform> imagesAndLocations = new Dictionary<ImageLocation, ImageAndImageTransform>();

        public GameDialog(Stream zipStream)
        {
            InitializeComponent();
            imagesAndLocations.Add(ImageLocation.Left, new ImageAndImageTransform() { ImageUsed = leftImage, ImageTransform = leftImageScaleTransform });
            imagesAndLocations.Add(ImageLocation.Center, new ImageAndImageTransform() { ImageUsed = centerImage, ImageTransform = centerImageScaleTransform });
            imagesAndLocations.Add(ImageLocation.Right, new ImageAndImageTransform() { ImageUsed = rightImage, ImageTransform = rightImageScaleTransform });
            imagesAndLocations.Add(ImageLocation.Background, new ImageAndImageTransform() { ImageUsed = background, ImageTransform = backgroundImageScaleTransform });
            GameFile.Load(zipStream, this, this);
            actionList = GameFile.GameDialog["Opening"].Actions.GetEnumerator();
            ContinueAction();
        }

        // Executes when the user navigates to this page.
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
        }

        private void ToggleUI()
        {
            if (borderDialog.Opacity != 0)
            {
                borderDialog.FadeOut();
            }
            else
            {
                borderDialog.FadeIn(0.75);
            }
        }

        private IEnumerator<IDialogAction> actionList;
        public void ContinueAction()
        {
            if (actionList.MoveNext() == false)
            {
                return;
            }
            IDialogAction action = actionList.Current;
            action.StartAction();
            if ( action.WaitForInput == false )
            {
                ContinueAction();
            }
        }

        private void borderDialog_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            ContinueAction();
        }

        public void SetText(string header, string text)
        {
            textBlockName.Text = header;
            for (int i = 1; i <= text.Length; i++)
            {
                string partialText = text.Substring(0, i);
                Dispatcher.DelayInvoke(TimeSpan.FromMilliseconds(25 * i),
                                        new Action(() => { textBlockText.Text = partialText; }));
            }
        }

        public void ClearImages()
        {
            foreach (ImageAndImageTransform item in imagesAndLocations.Values)
            {
                item.ImageUsed.Source = null;
            }
        }

        public void ClearImage(ImageLocation location)
        {
            imagesAndLocations[location].ImageUsed.Source = null;
        }

        public Image GetImageItem(ImageLocation location, bool flipped)
        {
            ImageAndImageTransform image = imagesAndLocations[location];
            if (flipped)
            {
                image.ImageTransform.ScaleX = -1;
            }
            else
            {
                image.ImageTransform.ScaleX = 1;
            }
            return image.ImageUsed;
        }

        public void TransitionEnterImage(ImageLocation location, ImageEnterTransition transition)
        {
            ImageAndImageTransform image = imagesAndLocations[location];
            switch (transition)
            {
                case ImageEnterTransition.FadeIn:
                    image.ImageUsed.FadeIn();
                    break;
                case ImageEnterTransition.EnterLeft:
                    if (image.ImageTransform.ScaleX == -1)
                    {
                        image.ImageUsed.EnterFromRight(image.ImageUsed.ActualWidth);
                    }
                    else
                    {
                        image.ImageUsed.EnterFromLeft(image.ImageUsed.ActualWidth);
                    }
                    break;
                case ImageEnterTransition.EnterRight:
                    if (image.ImageTransform.ScaleX == -1)
                    {
                        image.ImageUsed.EnterFromLeft(image.ImageUsed.ActualWidth);
                    }
                    else
                    {
                        image.ImageUsed.EnterFromRight(image.ImageUsed.ActualWidth);
                    }
                    break;
                case ImageEnterTransition.EnterBottom:
                    break;
                case ImageEnterTransition.EnterTop:
                    break;
                default:
                    break;
            }
        }

        public void TransitionExitImage(ImageLocation location, ImageExitTransition transition)
        {
            ImageAndImageTransform image = imagesAndLocations[location];
            switch (transition)
            {
                case ImageExitTransition.FadeOut:
                    image.ImageUsed.FadeOut();
                    break;
                case ImageExitTransition.ExitRight:
                    break;
                case ImageExitTransition.ExitLeft:
                    break;
                case ImageExitTransition.ExitTop:
                    break;
                case ImageExitTransition.ExitBottom:
                    break;
                default:
                    break;
            }
        }
    }
}
